iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
Security

資安小白的密碼學從0到1-CryptoHack平台解題紀錄系列 第 18

【Day 17】柵欄密碼&密碼棒實作

  • 分享至 

  • xImage
  •  

前言

今天會先介紹柵欄密碼,之後為最後一個古典密碼實作- Scytale 密碼棒
明天進入現代密碼!

Rail-fence Cipher 柵欄密碼

  • 置換式加密
  • 可以為蠻多形式的,這裡主要為W型跟一般型

這裡我不確定怎麼分,因為網路上查有查到這兩種

  • W型的
    明文由上至下順序寫上,當到達最低部時,再回頭向上,一直重複直至整篇明文寫完為止
    之後密文為由上一列一列接在一起輸出
    e.g.
    設plaintext : CODEBREAKING, rails = 3,則會表示為以下
    https://ithelp.ithome.com.tw/upload/images/20230927/20162613w7CKop0IU8.png
    encryptext : CBKOERAIGDEN

  • 一般型的
    把要加密的明文分成N個一組,然後把每組的第i個字連起來
    e.g.
    設plaintext : THEREISACIPHER, rails = 2
    rails = 2 -> 兩個一組
    得到:TH ER EI SA CI PH ER
    先取出第一個字母:TEESCPE
    再取出第二個字母:HRIAIHR
    encryptext : TEESCPEHRIAIHR

Scytale 密碼棒

https://ithelp.ithome.com.tw/upload/images/20230927/20162613QPs92nYFi6.png

加密過程大概是
如有個棒子可寫下四個字母繞成圓圈(4列)
且5個字母可連成一線(1列有5個字母)。
plaintext:"HELPMEIAMUNDERATTACK".
之後5個字母為一列,總共4列

row = 4, letters = 5


H E L P M
E I A M U
N D E R A
T T A C K


最後由上到下連在一起,即為密文
encryptext : "HENTEIDTLAEAPMRCMUAK"
解密的話就是反過來

row = 5, letters = 4
假設編碼文為"HENTEIDTLAEAPMRCMUAK"
_______________
H E N T---------
E I D T---------
L A E A---------
P M R C---------
M U A K---------
_______________
==>"HELPMEIAMUNDERATTACK"

來實作吧!

流程如下

  • 輸入要處理的字串 -> select 1 or 2
    • select = 1(加密) -> 輸入一列要幾個字元(letters) -> 計算rows ->
      呼叫en_or_decrypt(plaintext, rows, letters) -> 輸出處理完後的字串
    • select = 2(解密) -> 輸入一列要幾個字元(letters) -> 計算rows ->
      rows, letters值交換 ->
      呼叫en_or_decrypt(plaintext, rows, letters) -> 輸出處理完後的字串
def en_or_decrypt(plaintext, rows, letters):
    encryptext = ""
    arr = [[-1 for _ in range(letters)] for _ in range(rows)]
    x = 0
    y = 0
    for i in plaintext :
        arr[x][y] = i
        y+=1
        if y == letters :
            y = 0
            x += 1
    for i in range(0, letters):
        for j in range(0, rows):
            if arr[j][i] == -1:
                encryptext += " "
            else :
                encryptext += str(arr[j][i])
    return encryptext


def main():
    plaintext = str(input('input string\n>>'))
    select = int(input("input 1 or 2 (Encode / Decode)\n>>"))
    letters = int(input("How many letters of row\n>>"))
    rows = len(plaintext) // letters
    if len(plaintext) % letters > 0:
        rows += 1
    if select == 1 :
        print(f"encryptext:{en_or_decrypt(plaintext, rows, letters)}|END")
    else :
        rows, letters = letters, rows
        print(f"decryptext:{en_or_decrypt(plaintext, rows, letters)}|END")


if __name__ == "__main__":
    main()

output

  • select 1(加密)

plaintext=Hello my friend, letters = 5
輸出後面會有|END表示結尾,這樣如果空格在最後面比較看得清楚

https://ithelp.ithome.com.tw/upload/images/20230928/201626138jX6QnSMSM.png

  • 對照線上解碼器

網站輸出內容會以 " _ " 表示空格,且會全部都為大寫

https://ithelp.ithome.com.tw/upload/images/20230928/20162613l5XcGZoPPt.png

結果相同

  • select 2(解密)

plaintext=H remilyel nofd, letters = 5
https://ithelp.ithome.com.tw/upload/images/20230928/201626133UUyRP2N0i.png

  • 對照線上解碼器

網站輸出內容會以 " _ " 表示空格,且會全部都為大寫

https://ithelp.ithome.com.tw/upload/images/20230928/20162613AmRR8YhA9x.png

結果相同

小結

柵欄密碼好像有點多種,不知道要寫哪個,就寫了跟柵欄密碼蠻像的密碼棍,也順利結束惹,明天正式回到Cryptohack平台接觸現代密碼!

題外話:這發文時間好危險w 想說密碼棍有寫過應該可以寫很快,但對於python還是...不太熟,差點出事XD

參考資料

密碼棍解碼器 : https://dencode.com/cipher/scytale
密碼棍維基百科 :https://zh.wikipedia.org/wiki/%E5%AF%86%E7%A2%BC%E6%A3%92


上一篇
【Day 16】Vigenère 密碼實作
下一篇
【Day 18】Symmetric CryptoGraphy01 - AES小入門 &架構
系列文
資安小白的密碼學從0到1-CryptoHack平台解題紀錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言